//
//  GeneralViewController.m
//  McRemote
//
//  Created by Magic on 1/7/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "GeneralViewController.h"
#import "ModelManager.h"
#import "Group.h"
#import "Command.h"
#import "MRMessageCenter.h"
#import "MRClient.h"
#import "MRAlertView.h"

@interface GeneralViewController () {
    Group *_group;
}

@property (nonatomic, weak) GridView *gridView;
@property (nonatomic, strong) NSMutableArray *commandList;
- (void)loadCommandsFromDataBase;
- (NSInteger)numberOfEmptyPage;
- (void)reportConnectionLost;

@end

@implementation GeneralViewController

@synthesize gridView = _gridView;
@synthesize commandList = _commandList;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle

- (void)awakeFromNib
{
    self.navigationItem.title = NSLocalizedString(self.title, @"");
    self.navigationController.tabBarItem.title = NSLocalizedString(self.title, @"");
}

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
 */
- (void)loadView
{
    NSString *bgPath = [[NSBundle mainBundle] pathForResource:@"bg" ofType:@"png"];
    UIImageView *bgView = [[UIImageView alloc] initWithImage:[UIImage imageWithContentsOfFile:bgPath]];
    bgView.userInteractionEnabled = YES;
    
    GridView *gridView = [[GridView alloc] initWithFrame:CGRectMake(0, 0, 320, 367)];
    gridView.gridViewDataSource = self;
    gridView.gridViewDelegate = self;
    
    [bgView addSubview:gridView];
    
    gridView.scrollIndicatorInsets = UIEdgeInsetsMake(8, 0, 0, 10);
    gridView.backgroundColor = [UIColor clearColor];
    gridView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
    
    self.view = bgView;
    self.gridView = gridView;
    
    [self loadCommandsFromDataBase];
    
    [gridView reloadData];
}

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.navigationItem.rightBarButtonItem = self.editButtonItem;
}

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];
    
    if (editing) {
        // Add a page in gridView to get ready for cell addition
        self.gridView.pageCount++;
    }
    else {
        // Remove empty pages at the end of gridView 
        int number = [self numberOfEmptyPage];        
        self.gridView.pageCount -= number;
    }
    
    self.gridView.editing = editing; 
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - GridViewDataSource protocol implementation

- (NSInteger)numberOfPagesInGridView:(GridView *)gridView
{
    int count = [self.commandList count];
    
    if (count%9 == 0) {
        return count/9;
    }
    else return (count/9+1);
}

- (GridViewCell *)gridView:(GridView *)gridView cellAtIndex:(NSInteger)index
{
    if (index >= [self.commandList count]) {
        return nil;
    }
    
    id cmd = [self.commandList objectAtIndex:index];
    
    if (cmd && cmd != [NSNull null]) {
        Command *command = (Command *)cmd;
        
        GridViewCell *cell = [GridViewCell emptyGridCell];
        cell.titleLabel.text = NSLocalizedString(command.title, @"");
        [cell.iconButton setImage:[UIImage imageNamed:command.icon] forState:UIControlStateNormal];
        
        return cell;
    }
    else return nil;
}

- (BOOL)gridView:(GridView *)gridView canEditCellAtIndex:(NSInteger)index
{
    if (index >= [self.commandList count]) {
        return YES;
    }
    
    id cmd = [self.commandList objectAtIndex:index];
    
    if (cmd == [NSNull null]) {
        return YES;
    }
    else {
        Command *command = (Command *)cmd;
        if (command.editable) {
            return YES;
        }
        else return NO;
    }
}

- (void)gridView:(GridView *)gridView commitEditingStyle:(GridViewCellEditingStyle)editingStyle forCellAtIndex:(NSInteger)index
{
    if (editingStyle == GridViewCellEditingStyleDelete) {
        // Remove from commandList
        Command *command = [self.commandList objectAtIndex:index];
        [self.commandList replaceObjectAtIndex:index withObject:[NSNull null]];
        
        // Remove from database
        [[ModelManager sharedManager] removeCommand:command];
        
        // Remove cell from gridView
        [gridView deleteCellAtIndex:index];
    }
    else if (editingStyle == GridViewCellEditingStyleInsert) {
        
        NSMutableDictionary *sender = [[NSMutableDictionary alloc] initWithCapacity:1];
        [sender setObject:[NSNumber numberWithInt:index] forKey:@"index"];
        [self performSegueWithIdentifier:@"GeneralToAdd" sender:sender];
    }
}

#pragma mark - GridViewDelegate protocol implementation

- (GridViewCellEditingStyle)gridView:(GridView *)gridView editingStyleForCellAtIndex:(NSInteger)index
{
    if (index >= [self.commandList count]) {
        return GridViewCellEditingStyleInsert;
    }
    
    id cmd = [self.commandList objectAtIndex:index];
    if (cmd == [NSNull null]) {
        return GridViewCellEditingStyleInsert;
    }
    else {
        Command *command = (Command *)cmd;
        if (command.editable) {
            return GridViewCellEditingStyleDelete;
        }
        else return GridViewCellEditingStyleNone;
    }
}

- (void)gridView:(GridView *)gridView tapOnCell:(GridViewCell *)cell
{
    if (cell.editingStyle == GridViewCellEditingStyleDelete) {
        
        NSMutableDictionary *sender = [[NSMutableDictionary alloc] initWithCapacity:2];
        
        NSInteger index = [gridView indexForCell:cell];
        [sender setObject:[NSNumber numberWithInt:index] forKey:@"index"];
        
        Command *command = [self.commandList objectAtIndex:index];
        [sender setObject:command forKey:@"command"];
        
        [self performSegueWithIdentifier:@"GeneralToAdd" sender:sender];
    }
    else if (cell.editingStyle == GridViewCellEditingStyleNone) {
        // Report if connection is lost
        if (![MRClient sharedClient].connected) {
            [self reportConnectionLost];
            return;
        }
        
        // Execute remote control
        NSInteger index = [gridView indexForCell:cell];
        Command *command = [self.commandList objectAtIndex:index];
        if (command.keycode >= 0) {
//            if (command.flag > 0) {
//                [[MRMessageCenter sharedCenter] sendKeycode:command.keycode withFlag:command.flag];
//            }
//            else {
//                [[MRMessageCenter sharedCenter] sendKeycode:command.keycode];
//            }
            
            BOOL annotated = YES;
            if ([_group.name isEqualToString:@"General"]) {
                annotated = NO;
            }
            else if ([_group.name isEqualToString:@"App"]) {
                if ([command.title isEqualToString:@"Switch App"]) {
                    annotated = NO;
                }
            }
            [[MRMessageCenter sharedCenter] sendKeycode:command.keycode withFlag:command.flag annotated:annotated];
        }
        else {
            [[MRMessageCenter sharedCenter] sendCommandWithTitle:command.title group:command.belongsTo.name];
        }
        
    }
}

- (void)gridView:(GridView *)gridView longPressOnCell:(GridViewCell *)cell
{
    
}

#pragma mark - segue

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([segue.identifier isEqualToString:@"GeneralToAdd"]) {
        UINavigationController *nc = segue.destinationViewController;
        AddCommandViewController *acc = (AddCommandViewController *)[nc topViewController];
        acc.delegate = self;

        // Pass the old command info to the new one
        NSDictionary *cellInfo = (NSDictionary *)sender;
        NSNumber *index = [cellInfo objectForKey:@"index"];
        acc.newCommandIndex = index.intValue;
        Command *cmd = [cellInfo objectForKey:@"command"];
        if (cmd) {
            acc.flag = cmd.flag;
            acc.keyCode = cmd.keycode;
            acc.title = cmd.title;
            acc.toUpdate = YES;
            acc.icon = cmd.icon;
        }
        else acc.toUpdate = NO;
    }
}

#pragma mark - AddCmdDelegate protocol implementation

- (void)cancelInAddCommandViewController:(AddCommandViewController *)acc
{
    [self dismissModalViewControllerAnimated:YES];
}

- (void)addCommandAtIndex:(NSInteger)index fromViewController:(AddCommandViewController *)acc
{
    // Add new command to database
    Command *newCommand = [[ModelManager sharedManager] addCommandWithTitle:acc.title keycode:acc.keyCode flag:acc.flag index:index icon:acc.icon group:_group];
    
    // Add new command to commandList
    while (index >= self.commandList.count) {
        [self.commandList addObject:[NSNull null]];
    }
    [self.commandList replaceObjectAtIndex:index withObject:newCommand];
    
    // Insert cell to GridView
    GridViewCell *cell = [GridViewCell emptyGridCell];
    cell.titleLabel.text = newCommand.title;
    [cell.iconButton setImage:[UIImage imageNamed:acc.icon] forState:UIControlStateNormal];
    [self.gridView insertCell:cell AtIndex:index];
    cell.editingStyle = GridViewCellEditingStyleDelete;
    
    // Turn the editing mode to done
    [self setEditing:NO animated:NO];
    
    // Dismiss AddCommandViewController
    [self dismissModalViewControllerAnimated:YES];
}

- (void)updateCommandAtIndex:(NSInteger)index fromViewController:(AddCommandViewController *)acc
{
    // Update command in database and commandList
    Command *oldCommand = [self.commandList objectAtIndex:index];
    
    oldCommand.title = acc.title;
    oldCommand.keycode = acc.keyCode;
    oldCommand.flag = acc.flag;
    oldCommand.icon = acc.icon;
    
    [[ModelManager sharedManager] saveUpdates];
    
    // Update cell in GridView
    GridViewCell *oldCell = [self.gridView cellAtIndex:index];
    oldCell.titleLabel.text = acc.title;
    oldCell.editingStyle = GridViewCellEditingStyleDelete;
    [oldCell.iconButton setImage:[UIImage imageNamed:acc.icon] forState:UIControlStateNormal];
    
    // Turn the editing mode to done
    [self setEditing:NO animated:NO];
    
    // Dismiss AddCommandViewController
    [self dismissModalViewControllerAnimated:YES];
}

#pragma mark - util

- (void)loadCommandsFromDataBase
{
    _group = [[ModelManager sharedManager] groupForName:self.title];
    NSSet *commands = [_group commands];
    
    // Get the max command index
    NSInteger cmdMaxIndex = 0;
    for (Command *cmd in commands) {
        if (cmd.index > cmdMaxIndex) {
            cmdMaxIndex = cmd.index;
        }
    }
    
    // Copy the commands from database to self.commandList, 
    //  set [NSNull null] where there's no command at index
    self.commandList = [[NSMutableArray alloc] initWithCapacity:cmdMaxIndex+1];
    for (int i = 0; i<cmdMaxIndex+1; i++) {
        [self.commandList addObject:[NSNull null]];
    }
    for (Command *cmd in commands) {
        [self.commandList replaceObjectAtIndex:cmd.index withObject:cmd];
    }
}

- (NSInteger)numberOfEmptyPage
{
    int ret = 0;
    BOOL pageIsEmpty = YES;
    
    while (pageIsEmpty) {
        int firstIndexOnPage = (self.gridView.pageCount-ret-1)*9;
        if (firstIndexOnPage < 0) break;
        
        for (int i=0; i<9; i++) {
            NSInteger cellIndex = firstIndexOnPage+i;
            
            if (cellIndex < [self.commandList count]) {
                id cmd = [self.commandList objectAtIndex:cellIndex];
                if (cmd != [NSNull null]) {
                    pageIsEmpty = NO;
                    break;
                }
            }
        }
        
        if (pageIsEmpty) ret++;
    }
    
    return ret;
}

- (void)reportConnectionLost
{
    [[MRAlertView sharedAlertView] showWithTitle:NSLocalizedString(@"No Connection",@"")];
}

@end
